package com.dongdongshop.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dongdongshop.pojo.item.TbItem;
import com.dongdongshop.service.item.ItemServiceI;
import com.dongdongshop.service.search.SearchService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.searchbox.client.JestClient;
import io.searchbox.core.Index;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Component
public class SearchServiceImpl implements SearchService {

    private String index_dkshop = "dkshop";
    private String type_tbItem = "tbitem";

    @Autowired
    private JestClient jestClient;

    @Reference
    private ItemServiceI itemService;

    @Override
    public void saveItemElasticSearch(Long[] ids) throws JsonProcessingException {
        for (Long id : ids) {
            List<TbItem> list = itemService.getItemList(id);
            for (TbItem item : list) {
                String itemJson = new ObjectMapper().writeValueAsString(item);
                //构建es文档对象
                Index esItem = new Index.Builder(itemJson)  //将该对象纳入构建范围
                        .index(index_dkshop)      //操作的索引(index==>库)
                        .type(type_tbItem)                //操作的类型(type==>表)
                        .id(String.valueOf(item.getId()))          //文档对象的ID
                        .build();
                try {
                    jestClient.execute(esItem);//执行
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public List<TbItem> findItemByElasticSearch(String name) throws IOException {
        MultiMatchQueryBuilder matchQuery =
                new MultiMatchQueryBuilder(name, "title", "sellPoint");

        HighlightBuilder highlight = new HighlightBuilder();
        highlight.field("sellPoint");
        highlight.field("title");
        highlight.preTags("<font color='red'>").postTags("</font>");  //高亮的样式

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.from(0);
        sourceBuilder.size(6);
        sourceBuilder.query(matchQuery);
        sourceBuilder.highlighter(highlight);

        //3.综合器输出查询语句字符串
        String queryStr = sourceBuilder.toString();
        System.out.println("综合器综合后的查询语句:=======>" + queryStr);

        //4.构建查询对象
        Search search = new Search.Builder(queryStr)
                .addIndex(index_dkshop)
                .addType(type_tbItem)
                .build();

        //5.查询
        SearchResult searchResult = jestClient.execute(search);
        List<SearchResult.Hit<TbItem, Void>> hits = searchResult.getHits(TbItem.class);

        List<TbItem> itemList = new ArrayList<>();
        for (SearchResult.Hit<TbItem, Void> hit : hits) {
            TbItem item = hit.source;
            Map<String, List<String>> highlightMap = hit.highlight;

            if (highlightMap != null && !highlightMap.isEmpty()) {
                List<String> titleList = highlightMap.get("title");
                List<String> sellPointList = highlightMap.get("sellPoint");

                if (titleList != null && !titleList.isEmpty()) {
                    item.setTitle(titleList.get(0));
                }
                if (sellPointList != null && !sellPointList.isEmpty()) {
                    item.setSellPoint(sellPointList.get(0));
                }
            }
            itemList.add(item);
            System.out.println(item.toString());
        }
        return itemList;
    }
}
